package cn.tpshion.devops.node;

import cn.tpshion.devops.common.enums.MsgType;
import cn.tpshion.devops.common.enums.NodeType;
import cn.tpshion.devops.common.CoreException;
import cn.tpshion.devops.common.constant.NodeConstant;
import cn.tpshion.devops.domain.entity.MsgData;
import cn.tpshion.devops.domain.entity.NodeData;
import cn.tpshion.devops.node.data.MavenData;
import cn.tpshion.devops.node.support.NodeContext;
import com.alibaba.fastjson2.JSON;
import lombok.extern.slf4j.Slf4j;
import org.apache.maven.shared.invoker.*;
import org.apache.maven.shared.utils.cli.CommandLineException;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;

import java.io.*;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;
import java.util.stream.Stream;

@Slf4j
@Component
public class MavenNode extends Node<MavenData> {

    @Value("${node.mavenHome}")
    private String mavenHome;

    @Value("${node.javaHome}")
    private String javaHome;

    @Override
    public NodeType nodeType() {
        return NodeType.MAVEN;
    }

    @Override
    public void handle(NodeContext nodeContext) throws Exception {
        log.info("MavenNode nodeContext:{}", nodeContext);
        sseHandle.sendMessage(nodeContext, new MsgData(MsgType.INFO, "开始执行maven节点"));

        Map<String, Object> contextData = nodeContext.getData();
        MavenData data = getData(nodeContext);
        log.info("MavenNode data:{}", data);
        sseHandle.sendMessage(nodeContext, new MsgData(MsgType.INFO, data.getCommand()));

        String pomPath = getPomPath(contextData, data);
        sseHandle.sendMessage(nodeContext, new MsgData(MsgType.INFO, "pomPath:" + pomPath));

        InvocationRequest request = new DefaultInvocationRequest();
        request.setInputStream(null);
        request.setBaseDirectory(new File(pomPath));
        request.setShowErrors(true);
        request.setShowVersion(true);
        request.setJavaHome(new File(javaHome));
        request.setGoals(Stream.of(data.getCommand()).collect(Collectors.toList()));

        Invoker invoker = new DefaultInvoker();
        invoker.setMavenHome(new File(data.getMavenHome()));
        invoker.setOutputHandler(s -> {
            log.info("maven log:{}", s);
            sseHandle.sendMessage(nodeContext, new MsgData(MsgType.INFO, s));
        });

        InvocationResult execute = invoker.execute(request);
        if(execute.getExitCode() != 0){
            CommandLineException executionException = execute.getExecutionException();
            throw new CoreException(Objects.isNull(executionException) ? "maven构建失败" : executionException.getMessage());
        }
        log.info("MavenNode execute:{}", JSON.toJSONString(execute));
    }

    private String getPomPath(Map<String, Object> contextData, MavenData data){
        String workspace = contextData.get(NodeConstant.WORKSPACE).toString();
        String pomPath = data.getPomPath();
        if(!StringUtils.hasText(pomPath)){
            return workspace;
        }
        if(pomPath.contains("#workspace#")){
            return pomPath.replaceAll("#workspace#", workspace);
        }
        return pomPath;
    }

    @Override
    protected MavenData getData(NodeContext nodeContext) {
        NodeData nodeData = nodeContext.getNodeData();
        MavenData data = JSON.parseObject(JSON.toJSONString(nodeData.getData()), MavenData.class);
        if(!StringUtils.hasText(data.getMavenHome())){
            data.setMavenHome(mavenHome);
        }
        return data;
    }

}
